﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ArtClub.Model;
using ArtClub.DAL;

namespace ArtClub.Controller
{
    public class AuctionCtr : IAuctionCtr
	{
		private IMemberCtr memberCtr;
        private IAuctionDB auctionDB;

        public AuctionCtr()
        {
			auctionDB = new AuctionDB();
			memberCtr = new MemberCtr();
        }

        public void Create(Auction auction)
        {
            auctionDB.Create(auction);
        }
        
        public Auction GetAuction(int id)
        {
          
            return auctionDB.GetAuction(id);
        }
        
        public List<Auction> ListAuctions()
        {
            return auctionDB.ListAuctions();
        }

        public List<Auction> ListAuctionsBySold(bool isSold)
        {
            return auctionDB.ListAuctionsBySold(isSold);
        }

		public void Update(Auction auction, Bid bid)
		{
            ValidateUpdate(auction, bid);
            auctionDB.Update(auction, bid);
		}

        private void ValidateUpdate(Auction auction, Bid bid)
        {
			// Check that the auction isn't closed.
			if (auction.Sold == true)
				throw new Exception("Auction is closed. No more bids allowed.");

			// Check that no other bid is higher or equal to the new bid.
			Bid highestBid = (from a in auction.Bids
							  orderby a.BidPrice descending
							  select a).FirstOrDefault();
			if (highestBid != null)
				if (highestBid.BidPrice >= bid.BidPrice)
					throw new Exception("Bid is too low.");

            if (double.IsNaN(bid.BidPrice))
                throw new Exception("Bid is only allowed to be a number");

            if (bid.Bidder.Points * 3 < bid.BidPrice)
                throw new Exception("Member doesn't have enough points.");
        }

		public void Close(Auction auction)
		{
            auctionDB.Close(auction);
		}

        public List<Member> ListMembersByPoint(int auctionId)
        {
			Auction auction = auctionDB.GetAuction(auctionId);

			Bid bid = (from a in auction.Bids
					   orderby a.BidPrice descending
					   select a).FirstOrDefault();

			if (bid != null)
			{
				int minPoints = (int)Math.Floor(bid.BidPrice / 3);
				return memberCtr.ListMembersByPoints(minPoints);
			}
			else
			{
				return memberCtr.ListMembers();
			}
        }
	}
}